import useMyFetch from "@/utils/fetch";
import { ref, Ref, unref, UnwrapRef } from "vue";
import useWatchPropeyty from "./useWatchProperty";

export interface UseFormOptions<T> {
  // 提交方式，默认post
  method?: "post" | "put";

  defaultModel?: Pick<T, keyof T> | Ref<T> | {};

  // 属性值改变后，是否触发提交
  autoSubmit?: boolean;
  // autoSubmit行为 依赖的属性
  depsKeys?: string[];

  // 重置后自动提交，一般用于列表搜索，默认关闭
  submitAfterReset?: boolean;
}

export const usePureForm = <T>(
  execute: Function,
  {
    defaultModel = {},
    depsKeys,
    autoSubmit,
    submitAfterReset,
  }: UseFormOptions<Partial<T>> = {}
) => {
  const refForm = ref();

  // 对目标对象属性监听，已做自动提交
  const proxyModel = useWatchPropeyty<Partial<T>>(
    defaultModel as T,
    () => autoSubmit && submit(),
    depsKeys
  );

  const model = ref<T>(proxyModel as T);

  const submit = async () => {
    await refForm.value?.validate();
    execute();
  };

  const reset = () => {
    refForm.value?.resetFields();
    if (submitAfterReset) submit();
  };

  return {
    refForm,
    model,
    reset,
    submit,
  };
};

const useForm = <TModel extends object = {}, TData = any>(
  url: string,
  {
    method = "post",
    formatModel = (e: UnwrapRef<TModel>) => e,
    ...formOptions
  }: UseFormOptions<Partial<TModel>> & {
    formatModel?: (e: UnwrapRef<TModel>) => any;
  } = {}
) => {
  const { execute, ...rest } = useMyFetch<TData>(url, { immediate: false });

  const { refForm, submit, reset, model } = usePureForm(execute, formOptions);

  rest[method](() => formatModel(unref(model))).json();

  return {
    ...rest,

    refForm,
    model,
    reset,
    submit,
  };
};

export default useForm;
